package com.rc.evcharger.dto.utils;

import com.rc.evcharger.common.constant.SocketConstant;
import com.rc.evcharger.common.redis.RedisDao;
import com.rc.evcharger.common.utils.DataUtil;
import com.rc.evcharger.common.utils.NumberUtil;
import com.rc.evcharger.dto.msg.TerminalMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;

/**
 * 主站响应或请求终端的消息
 *
 * @author yang
 */
public class MessageUtil {
    static Logger logger = LoggerFactory.getLogger(MessageUtil.class);

    public static final String MSTA = "02 00";//"63 03";//主站地址
    public static final String RTUA = "82 90 01 30";//终端地址
    public static final String START_SIGN = "68";//帧起始符
    public static final String END_SIGN = "16";//帧结束符
    public static final String SPLIT = DataUtil.SPLIT;//分隔符
    public static final String START = "68";
    public static final String END = "16";

    @Autowired
    public RedisDao redisDao;

    /**
     * 主站收到终端消息进行解码
     *
     * @param message
     * @return
     */
    public static List<TerminalMessage> decoder(String message) {
        TerminalMessage szTerminalMessage = null;
        String[] bcdCodes = message.split(DataUtil.SPLIT);
        List<Integer> starts = new ArrayList<>();
        List<Integer> ends = new ArrayList<>();
        List<TerminalMessage> result = new ArrayList<>();
        StringBuffer sb = null;
        for (int i = 0; i < bcdCodes.length; i++) {
            if (bcdCodes[i].equals(START)) {
                starts.add(i);
                continue;
            }
            if (bcdCodes[i].equals(END)) {
                ends.add(i);
                continue;
            }
        }
        if (starts.size() < 1 || ends.size() < 1) {
            logger.warn("异常数据1：" + message);
            return result;
        }
        for (Integer start : starts) {
            for (Integer end : ends) {
                try {
                    szTerminalMessage = new TerminalMessage(start, end, bcdCodes);
                    //  System.out.println(szTerminalMessage.toString());
                    if (!isExist(result, szTerminalMessage)) {
                        result.add(szTerminalMessage);
                    }
                } catch (Exception e) {
                    //e.printStackTrace();
                }
            }
        }
        if (result.size() < 1) {
            logger.warn("异常数据2：" + message);
        }
        return result;
    }

    private static boolean isExist(List<TerminalMessage> result, TerminalMessage stm) {
        for (TerminalMessage stm0 : result) {
            //if(stm0.getContral().equals(stm.getContral()) && stm0.getLength().equals(stm.getLength())){
            if (stm0.toString().equals(stm.toString())) {
                return true;
            }
        }

        return false;
    }

    /**
     * 将数据变成帧格式
     *
     * @param message
     * @return
     */
    public static String createFrame(TerminalMessage message) {

        StringBuffer sb = new StringBuffer("");
        try {
            sb.append(START_SIGN).append(SPLIT);

            //todo 兼容8位桩编号 拼接为12位
            if (message.getRtua().length() == 11) {
                message.setRtua(SocketConstant.JZ_00_00 + SPLIT + message.getRtua());
            }

            sb.append(message.getRtua()).append(SPLIT);
            if (message.getMsta() != null) {
                sb.append(message.getMsta()).append(SPLIT);
            } else {
                sb.append(MSTA).append(SPLIT);
            }
            sb.append(START_SIGN).append(SPLIT)
                    .append(message.getContral()).append(SPLIT).append(message.getLength()).append(SPLIT);
            if (message.getData() != null && message.getData().length() > 0) {
                sb.append(message.getData()).append(SPLIT);
            }

            String cs = NumberUtil.checkNum(sb.toString().split(SPLIT));
            if (cs.length() < 2)
                sb.append("0");
            sb.append(cs).append(SPLIT).append(END_SIGN);
        } catch (Exception e) {
            logger.error("将数据变成帧格式帧message：" + message.getBody());
            logger.error("将数据变成帧格式：" + e.toString());
        }
        return sb.toString();
    }

    /**
     * 公共构造响应帧
     *
     * @param message
     * @return
     */
    public static String getResponse(TerminalMessage message, String responseCode, boolean hasData) {
        try {
            if (!hasData) {
                message.setData("");
            }
            message.setContral(responseCode);
            int len = 0;
            if (message.getData().length() > 0) {
                len = message.getData().split(SPLIT).length;
            }
            String hex = Integer.toHexString(len);
            if (hex.length() == 1) {
                hex = "0" + hex;
            }
            hex = hex.toUpperCase();
            String length = hex + SPLIT + "00";
            message.setLength(length);
        } catch (Exception e) {
            logger.error("公共构造响应帧message：" + message.getBody());
            logger.error("公共构造响应帧：" + e.toString());
        }
        return createFrame(message);
    }


    /**
     * 构造数据响应帧
     *
     * @param message
     * @return
     */
    public static String getResponseData(TerminalMessage message, String responseCode, boolean hasData) {
        try {
//            if (!hasData) {
//                message.setData("");
//            }
            message.setContral(responseCode);
            int len = 0;
            if (message.getData().length() > 0) {
                len = message.getData().split(SPLIT).length;
            }
            String hex = Integer.toHexString(len);
            if (hex.length() == 1) {
                hex = "0" + hex;
            }
            hex = hex.toUpperCase();
            String length = hex + SPLIT + "00";
            message.setLength(length);
        } catch (Exception e) {
            logger.error("公共构造响应帧message：" + message.getBody());
            logger.error("公共构造响应帧：" + e.toString());
        }
        return createFrame(message);
    }

    /**
     * 处理数据分包，断针的问题.
     *
     * @param ctx
     * @param body
     * @return
     *//*
    public static String dealMsg(ChannelHandlerContext ctx, String body){
    	DataDealExp dde = new DataDealExp();
    	return dde.updateMsg(ctx, body);
    	String key = ctx.channel().id().asLongText();
		String[] bcdCodes=body.split(DataUtil.SPLIT);
		List<Integer> starts=new ArrayList<>();
		List<Integer> ends=new ArrayList<>();
		for(int i=0;i<bcdCodes.length;i++){
			if(bcdCodes[i].equals(START)){
				starts.add(i);	
				continue;
			}			
			if(bcdCodes[i].equals(END)){
				ends.add(i);
				continue;
			}		
		}
		if(starts.size()<1 || ends.size()<1){
			logger.warn("异常数据1："+body);
			if (redisDao.getRedis(key)==null) {
				redisDao.putRedis(key, body.trim());
			}else{
				//异常数据redis中进行拼接，然后在判断数据;
				redisDao.putRedis(key, redisDao.getRedis(key)+DataUtil.SPLIT+body);
				body = redisDao.getRedis(ctx.channel().id().asLongText());
				bcdCodes=body.split(DataUtil.SPLIT);
				starts.clear();
				ends.clear();
				for(int i=0;i<bcdCodes.length;i++){
					if(bcdCodes[i].equals(START)){
						starts.add(i);	
						continue;
					}			
					if(bcdCodes[i].equals(END)){
						ends.add(i);
						continue;
					}		
				}
				if(starts.size()<1 || ends.size()<1){
					logger.warn("拼接后，异常数据3："+body);
					return body;
				}
				redisDao.deleteSession(key);
				return body;
			}
			return body;			
		}
		return body;
    	
	}*/
    public static void main(String[] args) throws Exception {
        String data = "68 8E 07 00 01 00 00 73 00 00 00 FC 16";
        String data1 = "68 19 00 51 05 02 00 68 8E 04 00 01 00 00 FF D3 16 68 19 00 51 05 02 00 68 81 2C 00 01 00 00 00 00 00 00 00 31 C8 20 17 04 14 09 55 37 00 88 C8 00 00 00 89 C8 04 02 00 04 C9 00 00 8D C8 00 00 00 00 8E C8 00 00 00 00 EB 16";
        String data2 = "68 19 00 71 01 02 00 68 81 2C 00 01 00 00 00 00 00 00 00 31 C8 20 17 06 01 15 43 37 00 88 C8 45 79 33 89 C8 61 49 07 04 C9 18 15 8D C8 00 00 00 00 8E C8 00 00 00 00 B9 16 68 19 00 71 01 02 00 68 A4 00 00 01 16 68 19 00 71 01 02 00 68 81 16 00 01 00 00 00 00 00 00 00 31 C8 20 17 06 01 15 43 37 00 40 C8 00 01 C4 16";
        String d = "68 19 00 51 12 02 00 68 8E 04 00 02 00 00 FF E1 16 68 19 00 51 12 02 00 68 8E 04 00 02 00 01 00 E3 16";
        String a = "68 88 88 88 88 02 00 68 81 0C 00 01 00 00 00 00 00 00 00 40 C8 01 01 85 16";
        List<TerminalMessage> list = MessageUtil.decoder(a);
        for (TerminalMessage stm : list) {
            System.out.println(stm.getBody());
            System.out.println(stm.getContral());
            //Result result=new ElecControlResult("shenZhen");
            // ElecControlResult ecr= result.getResult(stm.getData());
            //System.out.println(ecr.getResult());
        }
    }
}
